package org.fiebug.spring.boot.seata.account.service;

import io.seata.spring.annotation.GlobalTransactional;
import org.fiebug.spring.boot.seata.account.feign.AccountFeign;
import org.fiebug.spring.boot.seata.account.repository.dao.AccountDAO;
import org.fiebug.spring.boot.seata.account.repository.entity.AccountEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.math.BigDecimal;

@Service
public class AccountService {
    @Resource
    private AccountService accountService;
    @Resource
    private AccountFeign accountFeign;
    @Resource
    private AccountDAO accountDAO;

    @GlobalTransactional
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void validate(Integer id) {
        boolean exists = accountDAO.existsById(id);
        Assert.isTrue(exists, "id not exists");
    }

    @GlobalTransactional
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void validate(AccountEntity account, BigDecimal amount) {
        boolean egt = account.getBalance().compareTo(amount) >= 0;
        Assert.isTrue(egt, "balance insufficient");
    }

    /**
     * 出账
     */
    @GlobalTransactional
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void credit(Integer id, BigDecimal amount) {
        validate(id);
        AccountEntity account = accountDAO.findById(id).get();
        accountService.credit(account, amount);
    }

    @GlobalTransactional
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void credit(AccountEntity account, BigDecimal amount) {
        validate(account, amount);
        account.setBalance(account.getBalance().subtract(amount));
        accountDAO.save(account);
    }

    /**
     * 入账
     */
    @GlobalTransactional
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void debit(Integer id, BigDecimal amount) {
        validate(id);
        AccountEntity account = accountDAO.findById(id).get();
        accountService.debit(account, amount);
    }


    @GlobalTransactional
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void debit(AccountEntity account, BigDecimal amount) {
        account.setBalance(account.getBalance().add(amount));
        accountDAO.save(account);
        if(amount.compareTo(BigDecimal.TEN) == 0) {
            throw new RuntimeException("金额太大，不让转账");
        }
    }

    /**
     * 转账
     */
    @GlobalTransactional
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void transfer(Integer creditId, Integer debitId, BigDecimal amount) {
        validate(creditId);
        validate(debitId);
        accountFeign.credit(creditId, amount);
        accountFeign.debit(debitId, amount);
    }

//    @GlobalTransactional
//    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
//    public void transfer(AccountEntity creditAccount, AccountEntity debitAccount, BigDecimal amount) {
//        validate(creditAccount, amount);
//        accountService.credit(creditAccount, amount);
//        accountService.debit(debitAccount, amount);
//    }
}
